Serverless Express + AWS Lambda + API Gateway の構成を AWS CDK で作成してみた
こんにちは、CX 事業本部製造ビジネステクノロジー部の若槻です。
Serverless Express は、AWS Lambda などのサーバーレス環境で Express.js を利用した REST API を構築できるライブラリです。
今回は、Serverless Express + AWS Lambda + API Gateway の構成を AWS CDK でデプロイして作成してみました。
試してみた
パッケージの導入
いくつかのパッケージ npm からインストールして導入します。
Serverless Express
@codegenie/serverless-express
をインストールします。
npm i @codegenie/serverless-express
最近、Serverless Express が CodeGenie に移行したので、古い方のパッケージをインストールしないように注意してください。
その他
express および cors(必要な場合)をインストールします。
npm i express npm i cors npm i -D @types/cors
Lambda コード
Lambda ハンドラーのコードです。/companies
パスへの POST メソッドのリクエストのルーティングを設定しています。
import serverlessExpress from '@codegenie/serverless-express'; import cors from 'cors'; import express, { Request, Response } from 'express'; const app = express(); app.use(cors()); app.use(express.json()); app.post('/companies', async (req: Request, res: Response): Promise<void> => { res.status(201).send({ ...req.body, id: 'c123' }); }); export const handler = serverlessExpress({ app });
CDK コード
AWS Lambda と API Gateway を作成する CDK スタックのコードです。LambdaRestApi
コンストラクトクラスを使用することにより、Lambda プロキシ統合の REST API を作成できます。
import { aws_lambda, aws_lambda_nodejs, aws_apigateway, Stack, Duration, CfnOutput, } from 'aws-cdk-lib'; import { Construct } from 'constructs'; export class CdkSampleStack extends Stack { constructor(scope: Construct, id: string) { super(scope, id); /** * Lambda 関数を作成 */ const restApiFunc = new aws_lambda_nodejs.NodejsFunction( this, 'RestApiFunc', { architecture: aws_lambda.Architecture.ARM_64, runtime: aws_lambda.Runtime.NODEJS_20_X, entry: 'src/rest-api-router.ts', } ); /** * REST API を作成 */ const restApi = new aws_apigateway.LambdaRestApi(this, 'RestApi', { handler: restApiFunc, defaultCorsPreflightOptions: { allowOrigins: aws_apigateway.Cors.ALL_ORIGINS, allowMethods: aws_apigateway.Cors.ALL_METHODS, allowHeaders: aws_apigateway.Cors.DEFAULT_HEADERS, maxAge: Duration.minutes(5), }, // Web アプリケーションからの CORS リクエストを許可する場合はこの記述を追加 deployOptions: { stageName: 'v1', // 既定では "prod" になるため、適切なステージ名に変更 tracingEnabled: true, // AWS X-Ray によるトレースを有効化 }, }); /** * API Gateway エンドポイント */ new CfnOutput(this, 'RestApiEndpoint', { value: restApi.deploymentStage.urlForPath(), }); } }
動作確認
CDK でデプロイした API Gateway のエンドポイントに対して、/companies
パスへの POST メソッドのリクエストを送ると、{"Name":"Hello株式会社","id":"c123"}
というレスポンスが返ってきました。Serverless Express がちゃんと動いているようです。
$ curl -X POST -H "Content-Type: application/json" \ -d '{"Name":"Hello株式会社"}' \ https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/companies {"Name":"Hello株式会社","id":"c123"}
同じパスでも GET メソッドでリクエストを送ると、Cannot GET /companies
というエラーメッセージが返ってきます。(想定通り)
$ curl -X GET \ https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/companies <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Error</title> </head> <body> <pre>Cannot GET /companies</pre> </body>
ルーティングを設定していないパスにリクエストを送ると、Cannot POST /employees
というエラーメッセージが返ってきます。(想定通り)
$ curl -X POST -H "Content-Type: application/json" \ -d '{"Name":"Hello株式会社"}' \ https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/employees <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Error</title> </head> <body> <pre>Cannot POST /employees</pre> </body> </html>
おわりに
Serverless Express + AWS Lambda + API Gateway の構成を AWS CDK でデプロイして作成してみました。
どなたかの参考になれば幸いです。
参考
以上